Welcome.
In this lecture, we're going to be checking out another service called the Collection Service.
The purpose of the collection service is to give us the ability to add something called tags to instances
in our game.
A tag is simply a string that is attached to an instance, and these tags make it easier for us to uphold
programming principles like dry or don't repeat yourself.
This is because the collection service has functions where we are able to grab all of the instances
in our game that have a specific tag, making it much easier for us to interact with these instances
without needing to store them in folders.
Here in the Roblox API documentation, it describes the collection service as something that manages
groups or collections of instances with tags.
Tags are sets of strings applied to objects that replicate from the server to the client, and in Team
create.
They are also serialized when places are saved.
At the moment, tags are not visible within Roblox studio except with the use of a tag.
Editing plugin.
This is actually not true because Roblox Studio did update recently where we can now edit tags, uh,
directly on instances through the properties panel, and we don't necessarily need to use a tag editing
plugin.
However, tag editing plugins do have more features, so if you'd like to use that, I've also attached
one to this lecture.
Back in Roblox studio.
If I'd like to add a tag to an instance such as the spawn plate right here, I can select the spawn
location, and then I can go to my properties panel and scroll all the way down until I reach the tags
section.
Here I am able to add new strings that are going to be my tags.
For example, I could name this tag example tag and I can create it.
And now I have this new tag that has been created on my spawn location.
If I wanted to add this to like my base plate, then I can hit the plus button here.
And as you can see, my example tag shows up right there.
Another way that we can add tags to instances in our game is by using a tag editing plugin.
So I've attached this tag editing plugin to the lecture and we can go ahead and open it up.
And right here we can create a new tag.
I'll create another example tag.
And now here it shows my example tag in this menu.
And I can go ahead and select it.
And it gives me some extra options within this uh plugin to like change the icon.
I can change the color when we want to visualize them in our game.
So we actually have the option to see all the instances in our game as like a highlight.
So if I select my part here, as you can see this check box shows up and I can select that checkbox.
And now I have added this example tag to my spawn location.
And as you can see it also shows up within our properties menu.
And then if I wanted to visualize all of the items in my workspace that have this tag, I can go to
World View.
And as you can see, since I have this one selected, any instances in my game that have this example
tag are going to be highlighted purple.
And of course I can change this color to whatever I'd like as well.
This is just the extra features that a tag editing plugin has.
They aren't necessary, but they are a lot more useful in some situations.
Now an example application of using tags in our game is for example, creating kill bricks, and a common
approach would be to create our kill brick part, and then we would create a script inside of that part
that would reference the part, and then listen to its touched event.
And whenever a player touches it, we kill the player.
So what we're going to do here is we're just going to create a kill brick real quick.
We'll create a new part.
I'll make sure this part is anchored.
I'll change the color to something like red.
And I can just name this my kill brick.
And typically what we would do is we would add a script inside of our kill brick.
And inside of here we would make a reference to our kill brick.
I'll create a variable called brick and that's simply script dot parent.
And then from this we would refer to our brick, get the touched event and connect a function to listen
to that event.
We would get the other part that touched our part, and then we could check if a humanoid touched our
brick.
So we would create a variable called humanoid.
And what we would do is we would get other part dot parent, which would be the model of a character
if a player touched it.
And to confirm that we want to find, uh, the first child, which is a humanoid.
So if the parent of this part has a humanoid inside of it, then we know that this is a player's character.
And what we could do is we can check if it found a humanoid.
If it did, then we can set the humanoid health equal to zero.
And now we have scripted our kill brick.
So now if we go and play our game.
And I were to go walk over to my Kubrick.
As you can see, it successfully killed me.
Now, if I wanted to have multiple of these bricks, then my first thought may be to just copy and paste
or duplicate this part multiple times.
I'll just put one here.
I could put one here, duplicate it here.
Because usually if you're creating an orb game, you might have hundreds of these kill bricks.
However, this is a big problem because now we have multiple scripts that are responsible for handling
our kill bricks.
If we wanted to add any new features to our kill bricks in the future, then we would have to go and
edit each one of these scripts inside of our kill bricks.
And if you had hundreds of these kill bricks, that would be a very time consuming process.
This is where the collection service can come to save the day.
What we can do instead is we can tag these parts with a tag like Kill Brick, and then we can grab all
of those tagged parts and connect to their touched events from a single script.
Doing it that way is much easier and more efficient than copy and pasting the same script over and over.
So what I'm going to do is I'm going to keep one kill brick.
We're going to get rid of the script inside of it, and instead we're going to add a new tag to this
kill brick.
And we can just call this tag Kill Brick.
And now we are able to duplicate this part as many times as we would like, because they're all going
to have the same tag of Kill Brick.
Then we can create a new script inside of server script service.
I'm going to call this script my kill brick handler.
Then we could go ahead and create a variable to store our collection service.
So we'll call it collection service.
And we're going to use the Get Service function to grab the collection service.
And then to grab all of the instances in our game that have the kill brick tag.
What we can do is we can create a variable, I'm going to call it bricks, and we're going to refer
to the collection service and use a function inside of there called Get Tagged.
And this is going to return an array of objects in the game with a given tag.
In this case, the tag or the instances that we would like to grab would be the instances with the kill
brick tag.
Now that we have all of the instances in our game with this kill break tag, then we can loop through
every single brick inside of bricks.
And what we want to do is we want to listen to their touched event so we can do brick dot touched.
And instead of creating a lambda function for every single brick in our game, because that would be
kind of a waste of resources.
Instead, what we want to do is we want to create a function we'll call it on touched, which will get
passed the other part that touched a particular brick part.
And then instead we can simply pass the reference to this function instead.
That way, we aren't creating hundreds of lambda functions that are each listening to an individual
brick.
Instead, every single kill brick in our game are all going to refer back to one function, so that
helps save on memory.
And then inside of this function, we can do the exact same thing that we did before.
We'll check to see if the parent of this other part has a humanoid inside of it.
And if there is a humanoid.
Then we're just going to set the humanoids health equal to zero.
Now, if we go and play test the game, each one of these bricks should be able to kill me.
Because again, they have the kill brick tag and our script collects all of the instances in our game
with that tag, and we listen to each one of those bricks touched event.
So let's go ahead and test this out.
If I walk over to my part.
As you can see.
There we go.
It killed me.
Let's go ahead and test another one.
Let's go ahead and try this left, brick.
As you can see, that one killed me as well.
And one more time, we'll go test.
Maybe this one right here.
And as you can see, it has killed me.
Very cool.
Now, instead of having four separate scripts in each one of these, kill bricks or kill bricks are
now being handled by a singular script inside of server script service.
This is why the collection service helps us with the dry principle, because we don't have to repeat
ourselves, or we don't have to duplicate the same script over and over in our game.
Now, another cool thing we can do with the collection service is we can listen for when a new instance
gets added with a particular tag.
That way, during the runtime of our game, if, let's say a new brick gets added by another script
and we want that, uh, we want that part to be a kill brick, then what we could do is we could listen
for when that part is added and then listen to its touched event.
So inside of the collection service, there's an event we can get.
And we get this event from a function called get instance added signal.
So we would pass a tag which would return back to us an event that would fire every time a tag is added
to an object in our game, or any instance in our game that has that particular tag added to it.
In this case, the tag we want to listen to is our kill brick tag.
And then we can go ahead and connect to this event.
And what this event is going to pass to us is that particular instance in our game that had the kill
brick tag added to it.
So we'll just call it brick here.
And then we can do the exact same thing that we did in our for loop.
We're going to refer to the brick.
Get its touched event.
And then we're going to connect our on touched function.
So now any time a new part is created in our game, or any time a part in our game has this kill brick
tag added to it, this event's going to fire and this lambda function is going to execute, and that
means we're going to connect to the touched event of that particular part.
And that means it should kill our player.
So to test this out, what we're going to do is we're going to play test the game.
So as you can see right now, our game is running and I'm going to switch to the server view.
And I'm going to go ahead and duplicate one of these bricks.
So I'm going to do control D.
And now I've just created a new part during the runtime of our game.
And that means that event should have fired.
And this brick right here should also kill us.
So if we go and touch it, as you can see, perfect, it works just fine.
I'm also going to add a print statement in here we can print out something like New Kill brick was added.
So that way you can actually see this event being fired inside of the console.
So again if we go and play test.
And we switch to the server view and we duplicate one of these parts right when I hit control.
And D as you can see, new brick was added.
And that means we're listening to the touch event for this new brick.
Again we can duplicate it.
New kill brick was added.
We can duplicate it again and again and again and again.
Very very cool.
However, one small problem we might encounter is what if we would like to disable the functionality
for a particular object in our game when a tag is removed?
For example, if this part right here, let's say the tag of kill brick was removed.
Well, when the tag of kill brick is removed, maybe we don't want this brick to kill anybody anymore.
However, if we go and touch it, this brick still kills us.
And that's because we're still listening to the touch event for this particular part, even though it
doesn't have the kill brick tag anymore.
A way that we could avoid doing this is by listening to another event in the collection service, and
that event is get instance removing signal or removed signal.
And this is again where we would pass a tag.
And then the event would fire any time this given tag is removed from an instance.
So we could pass kill brick here.
And connect a function to get the brick when this event fires.
And what we're going to have to do is we're going to have to store each of these connections.
Because remember the connect function returns a connection.
And then we're going to have to disconnect that function from our touched event any time.
Uh one of these bricks has their tag removed.
So what we could do is we could create a table and we're going to call it connections.
And inside of this connections table, we're going to store a bunch of key value pairs.
The key is going to be the part itself.
While the value associated with that key is going to be the connection or the value that gets returned
from our connect function.
So what we're going to do when we loop through all of the bricks in our game, we're going to refer
to our connections table, and we're going to create a new key.
And that key is going to be our brick.
And we're going to set that equal to the return from our connect function.
So now we have stored all of the connections for each one of our bricks in our game.
And we're also going to want to do this exact same thing for when a new brick is added.
So we'll paste that in here as well.
And now what we could do is we can check when this tag gets removed from an instance, and we can check
if that instance has a connection inside of our connections table.
So we can check if inside of our connections table we have a key for this particular instance.
If we do, that means we need to go ahead and disconnect the function from that part's touched event
so we can do connections, pass our key which is the brick, and then we can go ahead and disconnect.
That connection.
And then we can also copy this thing here again and then set it equal to nil, which essentially just
removes this key from our connections table.
So now any time we have a part in our game that gets set up and has the touch event, listen to.
If that instance has the brick tag removed, then we disconnect the function listening to that touched
event, which means the part is no longer going to kill any of our players.
So we can go ahead and play test this and try it out.
So if I check out this part right here, which has the Kubrick tag, if I go ahead and remove this Kubrick
tag and I go back to the client, if I go and touch it, let's see if it kills me.
As you can see, the part no longer kills me, and that's because that removes signal got fired, which
allowed us to disconnect the function that was listening to the touched event from this particular part.
However, this part right here will still kill me.
This also works if we duplicate one of these kill bricks.
So as you can see, we added a new kill brick, which means this is a dangerous part that will kill
us.
But if we go ahead and remove the tag from it and then we go and touch it, as you can see, it no longer
kills us.
The collection service is an incredibly powerful and useful tool at your disposal that you're going
to be using a lot in your games.
Keep up the good work and I'll see you in the next lecture.